import { RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';

/**
 * 可配置的路由重用策略
 * route.routeConfig.data.reuse设为true的路由,执行缓存策略
 * 备注:需要规避按需加载的模块路由:route.routeConfig.loadChildren!=undefined的情况
 */
export class ConfigurableRouteReuseStrategy implements RouteReuseStrategy {

    handlers: { [key: string]: DetachedRouteHandle } = {};
    detachedToken: { [key: string]: string } = {};

    // 计算缓存的key值:获取全路由字符串拼接
    calcKey(route: ActivatedRouteSnapshot) {
        const url = route.pathFromRoot.map(x => x.url.map(u => u.path).join('/')).join(';');
        // console.debug('calcKey url: ' + url);
        if (!url.length) return undefined;
        return url;
    }

    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        // console.debug('CustomReuseStrategy:shouldDetach', route);
        if (!route.routeConfig) return false;
        if (route.routeConfig.loadChildren) return false;
        if (route.routeConfig.data && route.routeConfig.data.reuse) {
            // console.log(route);
            const key = this.calcKey(route);
            const token: string = sessionStorage.getItem('token') || '';
            if (key) this.detachedToken[key] = token;
            return true;
        }
        return false;
    }

    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        // console.debug('CustomReuseStrategy:store', route, handle);
        if (!route.routeConfig) return;
        if (route.routeConfig.loadChildren) return;
        if (route.routeConfig.data && route.routeConfig.data.reuse) {
            const key = this.calcKey(route);
            if (key) this.handlers[key] = handle;
        }
    }

    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        // console.debug('CustomReuseStrategy:shouldAttach', route);\
        if (!route.routeConfig) return false;
        if (route.routeConfig.loadChildren) return false;
        if (route.routeConfig.data && route.routeConfig.data.reuse) {
            const key = this.calcKey(route);
            const token: string = sessionStorage.getItem('token') || '';
            if (key) return !!this.handlers[key] && token === this.detachedToken[key];
        }
        return false;
    }

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        // console.debug('CustomReuseStrategy:retrieve', route);
        if (!route.routeConfig) return null;
        if (route.routeConfig.loadChildren) return null;
        if (route.routeConfig.data && route.routeConfig.data.reuse) {
            const key = this.calcKey(route);
            if (key) return this.handlers[key] || null;
        }
        return null;
    }

    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        // console.debug('CustomReuseStrategy:shouldReuseRoute', future, curr);
        return future.routeConfig === curr.routeConfig;
    }
}


export const RouterReuseStrategyProvider = {
    provide: RouteReuseStrategy,
    useClass: ConfigurableRouteReuseStrategy
};

// class DefaultStrategy implements RouteReuseStrategy {
//     shouldDetach(route: ActivatedRouteSnapshot): boolean {
//         return false;
//     }

//     store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {
//         // console.log('store:', route);
//     }

//     shouldAttach(route: ActivatedRouteSnapshot): boolean {
//         return false;
//     }

//     retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
//         // console.log('retrieve:', route);
//         return null;
//     }

//     shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
//         return future.routeConfig === curr.routeConfig;
//     }
// }
